using System.Diagnostics;
using System.Runtime.InteropServices;
using SerialInput;

#if WINDOWS
// Win32 API - 隐藏控制台窗口
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

const int SW_HIDE = 0;
#endif
Console.OutputEncoding = System.Text.Encoding.UTF8;
// 确保只运行一个实例
using var mutex = new Mutex(true, "SerialInputMutex", out bool createdNew);
if (!createdNew)
{
    return; // 已有实例在运行
}

#if WINDOWS
// 隐藏控制台窗口
var consoleWindow = GetConsoleWindow();
if (consoleWindow != IntPtr.Zero)
{
    ShowWindow(consoleWindow, SW_HIDE);
}
#endif

// 处理命令行参数
if (args.Length > 0)
{
    await HandleCommandLineArgs(args);
    return;
}

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddLogging(configure =>
{
    configure.ClearProviders();
    configure.AddConsole(); // 控制台输出
    configure.AddProvider(new FileLoggerProvider()); // 添加文件日志
});

builder.Services.AddHostedService<BarcodeWorkerService>();
builder.Services.AddSingleton<SerialPortManager>();

var host = builder.Build();

// 设置程序退出处理
Console.CancelKeyPress += (s, e) =>
{
    e.Cancel = true;
    host.StopAsync().Wait();
};

AppDomain.CurrentDomain.ProcessExit += (s, e) =>
{
    host.StopAsync().Wait();
};

await host.RunAsync();

// 命令行参数处理方法
static async Task HandleCommandLineArgs(string[] args)
{
    string command = args[0].ToLower();

    switch (command)
    {
        case "--install":
        case "/install":
            InstallAutoStart();
            break;
        case "--uninstall":
        case "/uninstall":
            UninstallAutoStart();
            break;
        case "--status":
        case "/status":
            CheckStatus();
            break;
        default:
            WriteLog($"未知命令: {command}");
            break;
    }

    await Task.Delay(2000); // 等待操作完成
}

static void InstallAutoStart()
{
    try
    {
        string exePath = Process.GetCurrentProcess().MainModule?.FileName ?? "";
        string appName = "SerialInput";

#if WINDOWS
        // 注册表方式设置开机自启
        using var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
            @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);

        if (key != null)
        {
            key.SetValue(appName, $"\"{exePath}\"");
            WriteLog("开机自启设置成功");
            Console.WriteLine("开机自启设置成功！");
        }
#else

        string autostartDir = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Personal),
            ".config", "autostart");

        Directory.CreateDirectory(autostartDir);

        string desktopFile = Path.Combine(autostartDir, $"{appName}.desktop");

        string desktopContent =
            "[Desktop Entry]\n" +
            "Type=Application\n" +
            $"Name={appName}\n" +
            $"Exec=\"{exePath}\"\n" +
            "Terminal=false\n" +
            "X-GNOME-Autostart-enabled=true\n";

        File.WriteAllText(desktopFile, desktopContent);

// 确保可执行权限
        try
        {
            Process.Start("chmod", $"+x \"{desktopFile}\"");
        }
        catch { }

        WriteLog("Linux 开机自启设置成功");
        Console.WriteLine("Linux 开机自启设置成功！");
#endif
    }
    catch (Exception ex)
    {
        WriteLog($"设置开机自启失败: {ex.Message}");
        Console.WriteLine($"设置失败: {ex.Message}");
    }
}

static void UninstallAutoStart()
{
    try
    {
        string appName = "SerialInput";

#if WINDOWS
        using var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
            @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);

        if (key?.GetValue(appName) != null)
        {
            key.DeleteValue(appName);
            WriteLog("已移除开机自启");
            Console.WriteLine("开机自启已移除！");
        }
        else
        {
            Console.WriteLine("未找到开机自启项");
        }
#else
        string desktopFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".config", "autostart", $"{appName}.desktop");
        if (File.Exists(desktopFile))
        {
            File.Delete(desktopFile);
            WriteLog("Linux 已移除开机自启");
            Console.WriteLine("Linux 开机自启已移除！");
        }
        else
        {
            Console.WriteLine("Linux 未找到开机自启项");
        }
#endif
    }
    catch (Exception ex)
    {
        WriteLog($"移除开机自启失败: {ex.Message}");
        Console.WriteLine($"移除失败: {ex.Message}");
    }
}
static void CheckStatus()
{
    try
    {
        string appName = "SerialInput";
        bool isAutoStart = false;

#if WINDOWS
        using var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
            @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");

        isAutoStart = key?.GetValue(appName) != null;
#else
        string desktopFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".config", "autostart", $"{appName}.desktop");
        isAutoStart = File.Exists(desktopFile);
#endif

        bool isRunning = Process.GetProcessesByName("scanner").Length > 1;

        Console.WriteLine($"开机自启: {(isAutoStart ? "已启用" : "未启用")}");
        Console.WriteLine($"运行状态: {(isRunning ? "正在运行" : "未运行")}");

        WriteLog($"状态检查 - 开机自启: {isAutoStart}, 运行中: {isRunning}");
    }
    catch (Exception ex)
    {
        WriteLog($"状态检查失败: {ex.Message}");
        Console.WriteLine($"状态检查失败: {ex.Message}");
    }
}

static void WriteLog(string message)
{
    try
    {
        string logPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "SerialInput");

        Directory.CreateDirectory(logPath);

        string logFile = Path.Combine(logPath, $"scanner_{DateTime.Now:yyyyMMdd}.log");
        string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}\r\n";

        File.AppendAllText(logFile, logEntry);
    }
    catch
    {
        // 忽略日志写入错误
    }
}